package cn.wp.common.core.web.interceptor;


import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.wp.common.core.WpVar;
import cn.wp.common.core.web.annotation.BindInterceptor;
import cn.wp.common.core.web.annotation.ClearInterceptor;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

/**
 * CallService 拦截器
 * Created by chenyb on 2019-09-24
 */
public class ControllerInterceptor extends WpAbstractInterceptor {

    public ControllerInterceptor(String[] pathPatterns, String[] ignores) {
        super(pathPatterns, ignores);
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
        if(handler instanceof HandlerMethod){
            HandlerMethod handlerMethod = (HandlerMethod)handler;

            Class<?> clazz = handlerMethod.getBeanType();
            Method method = handlerMethod.getMethod();

            List<Class<? extends WpAbstractInterceptor>> globalSkipInterceptors = this.interceptorRegistryProxy.getSkipInterceptors();
            List<Class<? extends WpAbstractInterceptor>> globalInterceptors = this.interceptorRegistryProxy.getInterceptors();

            List<Class<? extends WpAbstractInterceptor>> interceptors = CollectionUtil.newArrayList();
            Set<Class<? extends WpAbstractInterceptor>> skipInterceptors = CollectionUtil.newHashSet();
            // 全局清除
            skipInterceptors.addAll(globalSkipInterceptors);

            // normal controller
            ClearInterceptor classClearInterceptor = clazz.getAnnotation(ClearInterceptor.class);
            ClearInterceptor clearInterceptor = method.getAnnotation(ClearInterceptor.class);

            if(classClearInterceptor != null && classClearInterceptor.value() != null){
                skipInterceptors.addAll(Arrays.asList(classClearInterceptor.value()));
            }

            if(clearInterceptor != null && clearInterceptor.value() != null){
                skipInterceptors.addAll(Arrays.asList(clearInterceptor.value()));
            }


            for (Class<? extends  WpAbstractInterceptor> globalInterceptor : globalInterceptors){
                if(!skipInterceptors.contains(globalInterceptor)){
                    interceptors.add(globalInterceptor);
                }
            }

            // 移除使用绑定注解标注的同源拦截器
            List<Class<?>> skipBindClasses = CollectionUtil.newArrayList();
            for(Class<? extends  WpAbstractInterceptor> interceptor : interceptors){
                BindInterceptor bindInterceptor = AnnotationUtil.getAnnotation(interceptor, BindInterceptor.class);
                if(bindInterceptor != null){
                    Class<?>[] bindClasses = bindInterceptor.value();
                    for(Class<?> bindClass : bindClasses){
                        if(!interceptors.contains(bindClass)){
                            skipBindClasses.add(interceptor);
                        }
                    }
                }
            }
            for(Class<?> interceptor : skipBindClasses){
               interceptors.remove(interceptor);
            }

            // 可用拦截器
            request.setAttribute(WpVar.INTERCEPTORS, interceptors);
        }

        return true;
    }


}